#include "Common.h"
#include "Buffer.h"

namespace fx {

    Buffer::Buffer() {
        length_ = 0;
        offset_ = 0;
        data_ = boost::shared_array<boost::uint8_t>();
    }

    Buffer::Buffer(const Buffer& another) {
        if (this != &another) {
            length_ = another.length_;
            offset_ = another.offset_;
            data_ = another.data_;
        }
    }
    Buffer::Buffer(boost::uint32_t length) 
        : length_(length), offset_(0)
    {
        if (length_ > 0) {
            data_ = boost::shared_array<boost::uint8_t>(new boost::uint8_t[length_ + offset_]);
        }
    }
    Buffer::Buffer(const boost::uint8_t* data, boost::uint32_t length)
        : length_(length), offset_(0)
    {
        if (length_ > 0) {
            data_ = boost::shared_array<boost::uint8_t>(new boost::uint8_t[length_ + offset_]);
            if (data_) {
                memcpy(data_.get(), data, (length_ + offset_) * sizeof(boost::uint8_t));
            }
        }
    }
    Buffer::Buffer(const std::string& str)
        : length_(str.length()), offset_(0)
    {
        if (length_ > 0) {
            data_ = boost::shared_array<boost::uint8_t>(new boost::uint8_t[length_ + offset_]);
            if (data_) {
                memcpy(data_.get(), str.c_str(), (length_ + offset_) * sizeof(boost::uint8_t));
            }
        }
    }
    Buffer& Buffer::operator = (const Buffer& another) {
        if (this != &another) {
            length_ = another.length_;
            offset_ = another.offset_;
            data_ = another.data_;
        }
        return *this;
    }

    bool Buffer::operator ! () const {
        return length_ == 0;
    }

    Buffer::operator bool () const {
        return length_ != 0;
    }

    void Buffer::Resize(boost::uint32_t length) {
        if (length_ < length) {
            boost::shared_array<boost::uint8_t> new_data(new boost::uint8_t[offset_ + length]);
            if (offset_ + length_ > 0) {
                memcpy(new_data.get(), data_.get(), (length_ + offset_) * sizeof(boost::uint8_t));
            }
            data_ = new_data;
        }
        length_ = length;
    }

    void Buffer::Swap(Buffer& another) {
        if (this != &another) {
            std::swap(length_, another.length_);
            std::swap(offset_, another.offset_);
            data_.swap(another.data_);
        }
    }

}